1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package com.sun.org.apache.xml.internal.security.utils;
22
23
24
25 import java.io.IOException;
26 import java.io.OutputStream;
27 import java.security.AccessController;
28 import java.security.PrivilegedAction;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.Iterator;
32 import java.util.Map;
33 import java.util.Set;
34
35 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
36 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
37 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
38 import org.w3c.dom.Attr;
39 import org.w3c.dom.Document;
40 import org.w3c.dom.Element;
41 import org.w3c.dom.NamedNodeMap;
42 import org.w3c.dom.Node;
43 import org.w3c.dom.NodeList;
44 import org.w3c.dom.Text;
45
46
47
48
49
50
51
52
53 public class XMLUtils {
54
55 private static boolean ignoreLineBreaks =
56 AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
57 public Boolean run() {
58 return Boolean.getBoolean
59 ("com.sun.org.apache.xml.internal.security.ignoreLineBreaks");
60 }
61 });
62
63
64
65
66
67 private XMLUtils() {
68
69
70 }
71 public static Element getNextElement(Node el) {
72 while ((el!=null) && (el.getNodeType()!=Node.ELEMENT_NODE)) {
73 el=el.getNextSibling();
74 }
75 return (Element)el;
76
77 }
78
79
80
81
82
83
84
85 public static void getSet(Node rootNode,Set result,Node exclude ,boolean com) {
86 if ((exclude!=null) && isDescendantOrSelf(exclude,rootNode)){
87 return;
88 }
89 getSetRec(rootNode,result,exclude,com);
90 }
91 static final void getSetRec(final Node rootNode,final Set result,
92 final Node exclude ,final boolean com) {
93
94 if (rootNode==exclude) {
95 return;
96 }
97 switch (rootNode.getNodeType()) {
98 case Node.ELEMENT_NODE:
99 result.add(rootNode);
100 Element el=(Element)rootNode;
101 if (el.hasAttributes()) {
102 NamedNodeMap nl = ((Element)rootNode).getAttributes();
103 for (int i=0;i<nl.getLength();i++) {
104 result.add(nl.item(i));
105 }
106 }
107
108 case Node.DOCUMENT_NODE:
109 for (Node r=rootNode.getFirstChild();r!=null;r=r.getNextSibling()){
110 if (r.getNodeType()==Node.TEXT_NODE) {
111 result.add(r);
112 while ((r!=null) && (r.getNodeType()==Node.TEXT_NODE)) {
113 r=r.getNextSibling();
114 }
115 if (r==null)
116 return;
117 }
118 getSetRec(r,result,exclude,com);
119 }
120 return;
121 case Node.COMMENT_NODE:
122 if (com) {
123 result.add(rootNode);
124 }
125 return;
126 case Node.DOCUMENT_TYPE_NODE:
127 return;
128 default:
129 result.add(rootNode);
130 }
131 return;
132 }
133
134
135
136
137
138
139
140
141 public static void outputDOM(Node contextNode, OutputStream os) {
142 XMLUtils.outputDOM(contextNode, os, false);
143 }
144
145
146
147
148
149
150
151
152
153
154 public static void outputDOM(Node contextNode, OutputStream os,
155 boolean addPreamble) {
156
157 try {
158 if (addPreamble) {
159 os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes());
160 }
161
162 os.write(
163 Canonicalizer.getInstance(
164 Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS).canonicalizeSubtree(
165 contextNode));
166 } catch (IOException ex) {}
167 catch (InvalidCanonicalizerException ex) {
168 ex.printStackTrace();
169 } catch (CanonicalizationException ex) {
170 ex.printStackTrace();
171 }
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 public static void outputDOMc14nWithComments(Node contextNode,
188 OutputStream os) {
189
190 try {
191 os.write(
192 Canonicalizer.getInstance(
193 Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS).canonicalizeSubtree(
194 contextNode));
195 } catch (IOException ex) {
196
197
198 } catch (InvalidCanonicalizerException ex) {
199
200
201 } catch (CanonicalizationException ex) {
202
203
204 }
205 }
206
207
208
209
210
211
212
213
214 public static String getFullTextChildrenFromElement(Element element) {
215
216 StringBuffer sb = new StringBuffer();
217 NodeList children = element.getChildNodes();
218 int iMax = children.getLength();
219
220 for (int i = 0; i < iMax; i++) {
221 Node curr = children.item(i);
222
223 if (curr.getNodeType() == Node.TEXT_NODE) {
224 sb.append(((Text) curr).getData());
225 }
226 }
227
228 return sb.toString();
229 }
230
231
232 static String dsPrefix=null;
233 static Map namePrefixes=new HashMap();
234
235
236
237
238
239
240
241 public static Element createElementInSignatureSpace(Document doc,
242 String elementName) {
243
244 if (doc == null) {
245 throw new RuntimeException("Document is null");
246 }
247
248 if ((dsPrefix == null) || (dsPrefix.length() == 0)) {
249 return doc.createElementNS(Constants.SignatureSpecNS, elementName);
250 }
251 String namePrefix=(String) namePrefixes.get(elementName);
252 if (namePrefix==null) {
253 StringBuffer tag=new StringBuffer(dsPrefix);
254 tag.append(':');
255 tag.append(elementName);
256 namePrefix=tag.toString();
257 namePrefixes.put(elementName,namePrefix);
258 }
259 return doc.createElementNS(Constants.SignatureSpecNS, namePrefix);
260 }
261
262
263
264
265
266
267
268
269
270 public static boolean elementIsInSignatureSpace(Element element,
271 String localName) {
272 return ElementProxy.checker.isNamespaceElement(element, localName, Constants.SignatureSpecNS);
273 }
274
275
276
277
278
279
280
281
282
283 public static boolean elementIsInEncryptionSpace(Element element,
284 String localName) {
285 return ElementProxy.checker.isNamespaceElement(element, localName, EncryptionConstants.EncryptionSpecNS);
286 }
287
288
289
290
291
292
293
294
295
296
297 public static Document getOwnerDocument(Node node) {
298
299 if (node.getNodeType() == Node.DOCUMENT_NODE) {
300 return (Document) node;
301 }
302 try {
303 return node.getOwnerDocument();
304 } catch (NullPointerException npe) {
305 throw new NullPointerException(I18n.translate("endorsed.jdk1.4.0")
306 + " Original message was \""
307 + npe.getMessage() + "\"");
308 }
309
310 }
311
312
313
314
315
316
317
318
319
320
321 public static Document getOwnerDocument(Set xpathNodeSet) {
322 NullPointerException npe = null;
323 Iterator iterator = xpathNodeSet.iterator();
324 while(iterator.hasNext()) {
325 Node node = (Node) iterator.next();
326 int nodeType =node.getNodeType();
327 if (nodeType == Node.DOCUMENT_NODE) {
328 return (Document) node;
329 }
330 try {
331 if (nodeType==Node.ATTRIBUTE_NODE) {
332 return ((Attr)node).getOwnerElement().getOwnerDocument();
333 }
334 return node.getOwnerDocument();
335 } catch (NullPointerException e) {
336 npe = e;
337 }
338
339 }
340 throw new NullPointerException(I18n.translate("endorsed.jdk1.4.0")
341 + " Original message was \""
342 + (npe == null ? "" : npe.getMessage()) + "\"");
343 }
344
345
346
347
348
349
350
351
352
353 public static Element createDSctx(Document doc, String prefix,
354 String namespace) {
355
356 if ((prefix == null) || (prefix.trim().length() == 0)) {
357 throw new IllegalArgumentException("You must supply a prefix");
358 }
359
360 Element ctx = doc.createElementNS(null, "namespaceContext");
361
362 ctx.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:" + prefix.trim(),
363 namespace);
364
365 return ctx;
366 }
367
368
369
370
371
372
373 public static void addReturnToElement(Element e) {
374
375 if (!ignoreLineBreaks) {
376 Document doc = e.getOwnerDocument();
377 e.appendChild(doc.createTextNode("\n"));
378 }
379 }
380
381 public static void addReturnToElement(Document doc, HelperNodeList nl) {
382 if (!ignoreLineBreaks) {
383 nl.appendChild(doc.createTextNode("\n"));
384 }
385 }
386
387 public static void addReturnBeforeChild(Element e, Node child) {
388 if (!ignoreLineBreaks) {
389 Document doc = e.getOwnerDocument();
390 e.insertBefore(doc.createTextNode("\n"), child);
391 }
392 }
393
394
395
396
397
398
399
400 public static Set convertNodelistToSet(NodeList xpathNodeSet) {
401
402 if (xpathNodeSet == null) {
403 return new HashSet();
404 }
405
406 int length = xpathNodeSet.getLength();
407 Set set = new HashSet(length);
408
409 for (int i = 0; i < length; i++) {
410 set.add(xpathNodeSet.item(i));
411 }
412
413 return set;
414 }
415
416
417
418
419
420
421
422
423
424
425
426
427
428 public static void circumventBug2650(Document doc) {
429
430 Element documentElement = doc.getDocumentElement();
431
432
433 Attr xmlnsAttr =
434 documentElement.getAttributeNodeNS(Constants.NamespaceSpecNS, "xmlns");
435
436 if (xmlnsAttr == null) {
437 documentElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "");
438 }
439
440 XMLUtils.circumventBug2650internal(doc);
441 }
442
443
444
445
446
447
448
449 private static void circumventBug2650internal(Node node) {
450 Node parent=null;
451 Node sibling=null;
452 final String namespaceNs=Constants.NamespaceSpecNS;
453 do {
454 switch (node.getNodeType()) {
455 case Node.ELEMENT_NODE :
456 Element element = (Element) node;
457 if (!element.hasChildNodes())
458 break;
459 if (element.hasAttributes()) {
460 NamedNodeMap attributes = element.getAttributes();
461 int attributesLength = attributes.getLength();
462
463 for (Node child = element.getFirstChild(); child!=null;
464 child=child.getNextSibling()) {
465
466 if (child.getNodeType() != Node.ELEMENT_NODE) {
467 continue;
468 }
469 Element childElement = (Element) child;
470
471 for (int i = 0; i < attributesLength; i++) {
472 Attr currentAttr = (Attr) attributes.item(i);
473 if (namespaceNs!=currentAttr.getNamespaceURI())
474 continue;
475 if (childElement.hasAttributeNS(namespaceNs,
476 currentAttr.getLocalName())) {
477 continue;
478 }
479 childElement.setAttributeNS(namespaceNs,
480 currentAttr.getName(),
481 currentAttr.getNodeValue());
482
483
484 }
485 }
486 }
487 case Node.ENTITY_REFERENCE_NODE :
488 case Node.DOCUMENT_NODE :
489 parent=node;
490 sibling=node.getFirstChild();
491 break;
492 }
493 while ((sibling==null) && (parent!=null)) {
494 sibling=parent.getNextSibling();
495 parent=parent.getParentNode();
496 };
497 if (sibling==null) {
498 return;
499 }
500
501 node=sibling;
502 sibling=node.getNextSibling();
503 } while (true);
504 }
505
506
507
508
509
510
511
512 public static Element selectDsNode(Node sibling, String nodeName, int number) {
513 while (sibling!=null) {
514 if (ElementProxy.checker.isNamespaceElement(sibling, nodeName, Constants.SignatureSpecNS )) {
515 if (number==0){
516 return (Element)sibling;
517 }
518 number--;
519 }
520 sibling=sibling.getNextSibling();
521 }
522 return null;
523 }
524
525
526
527
528
529
530
531
532 public static Element selectXencNode(Node sibling, String nodeName, int number) {
533 while (sibling!=null) {
534 if (ElementProxy.checker.isNamespaceElement(sibling, nodeName, EncryptionConstants.EncryptionSpecNS )) {
535 if (number==0){
536 return (Element)sibling;
537 }
538 number--;
539 }
540 sibling=sibling.getNextSibling();
541 }
542 return null;
543 }
544
545
546
547
548
549
550
551
552 public static Text selectDsNodeText(Node sibling, String nodeName, int number) {
553 Node n=selectDsNode(sibling,nodeName,number);
554 if (n==null) {
555 return null;
556 }
557 n=n.getFirstChild();
558 while (n!=null && n.getNodeType()!=Node.TEXT_NODE) {
559 n=n.getNextSibling();
560 }
561 return (Text)n;
562 }
563
564
565
566
567
568
569
570
571 public static Text selectNodeText(Node sibling, String uri, String nodeName, int number) {
572 Node n=selectNode(sibling,uri,nodeName,number);
573 if (n==null) {
574 return null;
575 }
576 n=n.getFirstChild();
577 while (n!=null && n.getNodeType()!=Node.TEXT_NODE) {
578 n=n.getNextSibling();
579 }
580 return (Text)n;
581 }
582
583
584
585
586
587
588
589
590 public static Element selectNode(Node sibling, String uri,String nodeName, int number) {
591 while (sibling!=null) {
592 if (ElementProxy.checker.isNamespaceElement(sibling, nodeName, uri)) {
593 if (number==0){
594 return (Element)sibling;
595 }
596 number--;
597 }
598 sibling=sibling.getNextSibling();
599 }
600 return null;
601 }
602
603
604
605
606
607
608 public static Element[] selectDsNodes(Node sibling,String nodeName) {
609 return selectNodes(sibling,Constants.SignatureSpecNS,nodeName);
610 }
611
612
613
614
615
616
617 public static Element[] selectNodes(Node sibling,String uri,String nodeName) {
618 int size=20;
619 Element[] a= new Element[size];
620 int curr=0;
621
622 while (sibling!=null) {
623 if (ElementProxy.checker.isNamespaceElement(sibling, nodeName, uri)) {
624 a[curr++]=(Element)sibling;
625 if (size<=curr) {
626 int cursize= size<<2;
627 Element []cp=new Element[cursize];
628 System.arraycopy(a,0,cp,0,size);
629 a=cp;
630 size=cursize;
631 }
632 }
633 sibling=sibling.getNextSibling();
634 }
635 Element []af=new Element[curr];
636 System.arraycopy(a,0,af,0,curr);
637 return af;
638 }
639
640
641
642
643
644
645 public static Set excludeNodeFromSet(Node signatureElement, Set inputSet) {
646 Set resultSet = new HashSet();
647 Iterator iterator = inputSet.iterator();
648
649 while (iterator.hasNext()) {
650 Node inputNode = (Node) iterator.next();
651
652 if (!XMLUtils
653 .isDescendantOrSelf(signatureElement, inputNode)) {
654 resultSet.add(inputNode);
655 }
656 }
657 return resultSet;
658 }
659
660
661
662
663
664
665
666
667
668 static public boolean isDescendantOrSelf(Node ctx, Node descendantOrSelf) {
669
670 if (ctx == descendantOrSelf) {
671 return true;
672 }
673
674 Node parent = descendantOrSelf;
675
676 while (true) {
677 if (parent == null) {
678 return false;
679 }
680
681 if (parent == ctx) {
682 return true;
683 }
684
685 if (parent.getNodeType() == Node.ATTRIBUTE_NODE) {
686 parent = ((Attr) parent).getOwnerElement();
687 } else {
688 parent = parent.getParentNode();
689 }
690 }
691 }
692
693 public static boolean ignoreLineBreaks() {
694 return ignoreLineBreaks;
695 }
696 }